<template>
  <div>
    <el-popover placement="right" width="200" trigger="click" v-model="showOptList">
      <el-button slot="reference" size="mini" type="primary" @click="selected = []">添加检查项</el-button>
      <el-empty :image-size="50" v-if="!optionList.length" />
      <div class="opt-list-wrap" v-else>
        <div class="opt-list">
          <div
            class="item ellipsis"
            v-for="item in optionList"
            :key="item.chkitemCode"
            :title="item.chkitemName"
            :class="{
              selected: selected.includes(item.chkitemCode),
              disabled: selectedCodes.includes(item.chkitemCode)
            }"
            @click="selectItem(item)"
          >
            {{ item.chkitemName }}
          </div>
        </div>
        <div class="btn">
          <el-button size="mini" type="primary" :disabled="!selected.length" @click="btnAddItem">添加 {{ selected.length }}/{{ optionList.length - selectedCodes.length }}</el-button>
        </div>
      </div>
    </el-popover>
    <div class="list" v-if="list.length">
      <div class="item" v-for="(item, index) in list" :key="item.chkitemCode">
        <el-popconfirm title="移除此检查项？" confirm-button-text="移除" @confirm="list.splice(index, 1)">
          <i slot="reference" class="el-icon-close btn-remove pointer" />
        </el-popconfirm>
        <ScoreMode :ref="'ScoreMode' + index" v-model="item.data" :cfg="item" />
      </div>
    </div>
  </div>
</template>
<script>
// 选录入。inputMode 为 'ENTER_OPTION'
import { debounce } from '@/utils'
import ScoreMode from './ScoreMode'
export default {
  name: 'OptionInput',
  components: { ScoreMode },
  props: {
    value: { type: Array, default: () => [] },
    cfg: { type: Object, default: () => ({}) }
  },
  data() {
    return {
      showOptList: false,
      optionList: [], // 可选的检查项
      selected: [],
      list: [], // 已选的检查项
      prevData: ''
    }
  },
  computed: {
    innerValue: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit('input', val)
      }
    },
    selectedCodes() {
      const list = this.list || []
      return list.map(i => i.chkitemCode)
    }
  },
  watch: {
    cfg: {
      deep: true,
      immediate: true,
      handler() {
        this.initList()
      }
    },
    innerValue: {
      deep: true,
      immediate: true,
      handler(val) {
        const data = val || []
        const str = JSON.stringify(data)
        if (str === this.prevData) return
        this.prevData = str
        this.initList()
      }
    }
  },
  created() {
    this.btnAddItem = debounce(this.addItem, 1e3, true)
  },
  methods: {
    initList() {
      const cfgs = JSON.parse(JSON.stringify(this.cfg?.children || []))
      const data = JSON.parse(JSON.stringify(this.innerValue || []))
      if (!cfgs.length) return (this.list = [])

      const scoresMap = data.reduce((o, i) => !void (o[i.chkitemCode] = i) && o, {})
      const optionList = []
      const list = []
      cfgs.map(cfg => {
        cfg.data = {}
        const scoreData = scoresMap[cfg.chkitemCode]
        if (!scoreData) return optionList.push(cfg)

        cfg.data = scoreData
        optionList.push(cfg)
        list.push(cfg)
      })

      this.optionList = optionList
      this.list = list
    },
    async validate() {
      const list = this.list
      for (let i = 0; i < list.length; i++) {
        const name = 'ScoreMode' + i
        const ref = this.$refs[name]?.[0] || this.$refs[name]
        const valid = await ref?.validate().catch(() => false)
        if (!valid) return false
      }

      let data = list.map(i => i.data)
      data = JSON.parse(JSON.stringify(data))
      this.innerValue = data
      return true
    },
    selectItem(item) {
      const { selected } = this
      const code = item.chkitemCode
      const index = selected.findIndex(i => i === code)
      if (index > -1) selected.splice(index, 1)
      else selected.push(code)
    },
    addItem() {
      const { optionList, selected, list } = this
      this.showOptList = false
      const arr = optionList.filter(i => selected.includes(i.chkitemCode))
      this.list = list.concat(arr)
      this.selected = []
    }
  }
}
</script>
<style lang="scss" scoped>
.opt-list-wrap {
  margin: 0 -12px;
  .opt-list {
    max-height: 300px;
    overflow-y: auto;
  }
  .item {
    font-size: 12px;
    padding: 0 40px 0 20px;
    color: #606266;
    line-height: 34px;
    cursor: pointer;
    &:hover {
      background-color: #f5f7fa;
    }
  }
  .selected {
    color: #409eff;
    font-weight: 700;
    &::after {
      position: absolute;
      right: 20px;
      font-family: 'element-icons';
      content: '\e6da';
      font-size: 12px;
    }
  }
  .disabled {
    color: #c0c4cc;
    cursor: not-allowed;
  }
  .btn {
    text-align: right;
    padding: 10px 20px 0;
  }
}
.list {
  display: flex;
  flex-wrap: wrap;
  margin-top: 20px;
  .item {
    position: relative;
    border-radius: 5px;
    box-shadow: 0 2px 12px 0 rgba(black, 0.1);
    margin: 0 20px 20px 0;
  }
  .btn-remove {
    position: absolute;
    top: 0;
    right: 0;
    padding: 10px;
    &:hover {
      color: #409eff;
    }
  }
}
</style>
